﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ITypeFinder.cs" company="">
//   
// </copyright>
// <summary>
//   Classes implementing this interface provide information about types
//   to various services in the SmartStore engine.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Skymate.Core
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    /// <summary>
    ///     Classes implementing this interface provide information about types
    ///     to various services in the SmartStore engine.
    /// </summary>
    public interface ITypeFinder
    {
        Type[] Find(Func<Type, bool> predicate);

        /// <summary>
        /// The get assemblies.
        /// </summary>
        /// <param name="ignoreInactivePlugins">
        /// The ignore inactive plugins.
        /// </param>
        /// <returns>
        /// The <see cref="IList"/>.
        /// </returns>
        IList<Assembly> GetAssemblies(bool ignoreInactivePlugins = false);

        /// <summary>
        /// The find classes of type.
        /// </summary>
        /// <param name="assignTypeFrom">
        /// The assign type from.
        /// </param>
        /// <param name="assemblies">
        /// The assemblies.
        /// </param>
        /// <param name="onlyConcreteClasses">
        /// The only concrete classes.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        IEnumerable<Type> FindClassesOfType(
            Type assignTypeFrom, 
            IEnumerable<Assembly> assemblies, 
            bool onlyConcreteClasses = true);
    }

    /// <summary>
    ///     The i type finder extensions.
    /// </summary>
    public static class ITypeFinderExtensions
    {
        /// <summary>
        /// The find classes of type.
        /// </summary>
        /// <param name="finder">
        /// The finder.
        /// </param>
        /// <param name="onlyConcreteClasses">
        /// The only concrete classes.
        /// </param>
        /// <param name="ignoreInactivePlugins">
        /// The ignore inactive plugins.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> FindClassesOfType<T>(
            this ITypeFinder finder, 
            bool onlyConcreteClasses = true, 
            bool ignoreInactivePlugins = false)
        {
            return finder.FindClassesOfType(typeof(T), finder.GetAssemblies(ignoreInactivePlugins), onlyConcreteClasses);
        }

        /// <summary>
        /// The find classes of type.
        /// </summary>
        /// <param name="finder">
        /// The finder.
        /// </param>
        /// <param name="assignTypeFrom">
        /// The assign type from.
        /// </param>
        /// <param name="onlyConcreteClasses">
        /// The only concrete classes.
        /// </param>
        /// <param name="ignoreInactivePlugins">
        /// The ignore inactive plugins.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> FindClassesOfType(
            this ITypeFinder finder, 
            Type assignTypeFrom, 
            bool onlyConcreteClasses = true, 
            bool ignoreInactivePlugins = false)
        {
            return finder.FindClassesOfType(
                assignTypeFrom, 
                finder.GetAssemblies(ignoreInactivePlugins), 
                onlyConcreteClasses);
        }

        /// <summary>
        /// The find classes of type.
        /// </summary>
        /// <param name="finder">
        /// The finder.
        /// </param>
        /// <param name="assemblies">
        /// The assemblies.
        /// </param>
        /// <param name="onlyConcreteClasses">
        /// The only concrete classes.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> FindClassesOfType<T>(
            this ITypeFinder finder, 
            IEnumerable<Assembly> assemblies, 
            bool onlyConcreteClasses = true)
        {
            return finder.FindClassesOfType(typeof(T), assemblies, onlyConcreteClasses);
        }
    }
}